package com.example.demo.service.Impl;


import com.example.demo.ao.AttendanceRecordsAo;
import com.example.demo.ao.Holiday;
import com.example.demo.mapper.AttendanceReportMapper;
import com.example.demo.service.AttendanceReportService;
import com.example.demo.vo.AttendanceReportVo;
import com.example.demo.vo.AttendanceReportWeekVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

@Service
public class AttendanceReportServiceImpl implements AttendanceReportService {


    @Autowired
    private AttendanceReportMapper attendanceReportMapper;



    @Override
    public List<AttendanceReportVo> getAttendanceReport(AttendanceRecordsAo attendanceRecordsAo) {
        return attendanceReportMapper.getAttendanceReport(attendanceRecordsAo);
    }

    @Override
    public List<AttendanceReportWeekVo> getAttendanceReportWeek(AttendanceRecordsAo attendanceRecordsAo) {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate parseStart = LocalDate.parse(attendanceRecordsAo.getAttendanceDate(), formatter);
        LocalDate parseEnd = LocalDate.parse(attendanceRecordsAo.getAttendanceDateEnd(), formatter);
        List<AttendanceReportWeekVo> result = new ArrayList<>();
        long diffDays = ChronoUnit.DAYS.between(parseStart, parseEnd);
        if ("01".equals(attendanceRecordsAo.getType())){
            List<AttendanceReportWeekVo> attendanceReportWeek = attendanceReportMapper.getAttendanceReportWeek(attendanceRecordsAo);
            int day = calculateWorkDaysInRange(attendanceRecordsAo.getAttendanceDate(), attendanceRecordsAo.getAttendanceDateEnd());
            for (AttendanceReportWeekVo attendanceReportWeekVo : attendanceReportWeek) {
                attendanceReportWeekVo.setShouldAttendanceDay(day);
            }
            result.addAll(attendanceReportWeek);
        }else if ("02".equals(attendanceRecordsAo.getType())){
            List<AttendanceReportWeekVo> attendanceReportMonth = attendanceReportMapper.getAttendanceReportMonth(attendanceRecordsAo);
            int day = calculateWorkDays(attendanceRecordsAo);
            for (AttendanceReportWeekVo attendanceReportWeekVo : attendanceReportMonth) {
                attendanceReportWeekVo.setShouldAttendanceDay(day);
            }
            result.addAll(attendanceReportMonth);
        }


        return result;
    }







    //月度节假日
    private int calculateWorkDays(AttendanceRecordsAo attendanceRecordsAo) {
        // 提取年月部分
        String yearMonthStr = attendanceRecordsAo.getAttendanceDate().substring(0, 7);
        YearMonth yearMonth = YearMonth.parse(yearMonthStr);

        // 获取当月第一天和最后一天
        LocalDate start = yearMonth.atDay(1);
        LocalDate end = yearMonth.atEndOfMonth();

        // 查询该月份的节假日
        List<Holiday> holidays = attendanceReportMapper.getHolidaysBetween(start, end);

        int workDays = 0;
        LocalDate current = start;
        while (!current.isAfter(end)) {
            DayOfWeek dayOfWeek = current.getDayOfWeek();
            if (dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY) {
                LocalDate finalCurrent = current;
                boolean isHoliday = holidays.stream()
                        .anyMatch(holiday -> holiday.getHolidayDate().equals(finalCurrent));
                if (!isHoliday) {
                    workDays++;
                }
            }
            current = current.plusDays(1);
        }

        return workDays;
    }




    public int calculateWorkDaysInRange(String startDateStr, String endDateStr) {
        // 1. 把字符串变成 LocalDate
        LocalDate start = LocalDate.parse(startDateStr);
        LocalDate end   = LocalDate.parse(endDateStr);

        // 2. 查询区间内的所有节假日
        List<Holiday> holidays = attendanceReportMapper.getHolidaysBetween(start, end);

        int workDays = 0;
        LocalDate current = start;

        // 3. 逐日遍历
        while (!current.isAfter(end)) {
            DayOfWeek dayOfWeek = current.getDayOfWeek();
            // 跳过周末
            if (dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY) {
                LocalDate finalCurrent = current;
                boolean isHoliday = holidays.stream()
                        .anyMatch(h -> h.getHolidayDate().equals(finalCurrent));
                if (!isHoliday) {
                    workDays++;
                }
            }
            current = current.plusDays(1);
        }

        return workDays;
    }

}
